import json
import sys
import os
import time
import uuid
from datetime import datetime
import pandas as pd
curPath = os.path.abspath(os.path.dirname(__file__))
rootPath = os.path.split(curPath)[0]
sys.path.append(rootPath)


from web_查看单个策略结果 import run_backtest, run_backtest_klines,run_backtest_trade
from flask import Flask, request, make_response, send_file, render_template
import pymongo
pd.set_option('display.max_rows', None)

uuid = uuid.uuid4()
client = pymongo.MongoClient(host='localhost', port=27017)
db = client['backtest']
collection = db['backtest_statistical_data']
file_path_url = db['file_path_url']
url_id = []

app = Flask(__name__)


@app.route('/statistical/', methods=['POST'])
def statistical():

    try:
        # request_data = json.loads(request.data)
        #
        # # 策略名称
        # signal_name = request_data['signalName']
        #
        # # 策略参数
        # para = request_data['para']
        # para = eval(para)
        #
        # # 周期
        # rule_type = request_data['ruleType']
        #
        # # 时间范围
        # date_from = request_data['startTime']
        # date_to = request_data['endTime']
        #
        # # 币种
        # symbol = request_data['symbol']
        #
        # # 杠杆
        # leverage_rate = int(request_data['leverageRate'])
        #
        # # 滑点
        # slippage = float(request_data['slippage'])
        #
        # # 手续费
        # c_rate = float(request_data['c_rate'])

        # 返回数据类型
        # dtypes = request_data['dtypes'] if request_data['dtypes'] else 'json'

        # 是否返回k线图、资金曲线图
        # iskline = int(request_data['c_rate'])
        # isequitycurve = int(request_data['c_rate'])

        # 回测
        # res, res_df, trade = run_backtest(signal_name=signal_name, para=para, rule_type=rule_type, date_from=date_from,
        #                    date_to=date_to, symbol=symbol, leverage_rate=leverage_rate, slippage=slippage,
        #                    c_rate=c_rate)

        res, res_df, trade = run_backtest()
        dtypes = 'json'
        if dtypes == 'json':
            # web模式下请注释或删除
            iskline = 1
            isequitycurve = 1

            if iskline == 1:
                merge_df = trade.join(res_df, rsuffix='_r', how='outer')
                merge_df['candle_begin_time'] = merge_df.index
                df = merge_df[
                    ['candle_begin_time', 'open', 'close', 'low', 'high', 'median', 'upper', 'lower', 'signal',
                     'start_price', 'change', 'end_bar', 'end_price']]
                df.fillna(value=0, inplace=True)
                df['candle_begin_time'] = pd.to_datetime(df['candle_begin_time'], unit='s').dt.strftime(
                    '%Y-%m-%d %H:%M:%S')
                data_list = df.values.tolist()
                kline_url = f'http://10.16.252.237:5001/get_klines?uuid={uuid}'
            else:
                kline_url = ''

            if isequitycurve == 1:
                res_df['date'] = res_df.index
                res_df = res_df[['date', 'equity_curve']]
                res_df = res_df.values.tolist()
                curve_url = f'http://10.16.252.237:5001/get_curve?uuid={uuid}'
            else:
                curve_url = ''

            if kline_url or curve_url:
                data = {
                    'uuid': str(uuid),
                    'klines_data': data_list,
                    'curve_data': res_df
                }
                collection.insert_one(data)

            if not os.path.exists(os.path.join(os.pardir, 'files', 'json')):
                os.makedirs(os.path.join(os.pardir, 'files', 'json'))
            filename = f'files/json/statistical_{datetime.now().strftime("%Y%m%d%H%M%S")}.json'
            res.to_json(path_or_buf=os.path.join(os.pardir, filename), orient='index', force_ascii=False,
                       date_format='iso')

            file_path_url.insert_one({'jsonfiles': filename})

            return {
                    "code": 200,
                    "格式": "jsonfile",
                    '下载地址': 'http://10.16.252.237:5001/' + filename + '/download',
                    'k线图地址': kline_url,
                    '资金曲线图地址': curve_url
                    }

        elif dtypes == 'csv':
            # web模式下请注释或删除
            iskline = 1
            isequitycurve = 1

            if iskline == 1:
                merge_df = trade.join(res_df, rsuffix='_r', how='outer')
                merge_df['candle_begin_time'] = merge_df.index
                df = merge_df[['candle_begin_time', 'open', 'close', 'low', 'high', 'median', 'upper', 'lower', 'signal', 'start_price', 'change', 'end_bar', 'end_price']]
                df.fillna(value=0, inplace=True)
                data_list = df.values.tolist()
                kline_url = f'http://10.16.252.237:5001/get_klines?uuid={uuid}'
            else:
                kline_url = ''

            if isequitycurve == 1:
                res_df['date'] = res_df.index
                res_df = res_df[['date', 'equity_curve']]
                res_df = res_df.values.tolist()
                curve_url = f'http://10.16.252.237:5001/get_curve?uuid={uuid}'
            else:
                curve_url = ''

            if kline_url or curve_url:
                data = {
                    'uuid': str(uuid),
                    'klines_data': data_list,
                    'curve_data': res_df
                }
                collection.insert_one(data)

            if not os.path.exists(os.path.join(os.pardir, 'files', 'csv')):
                os.makedirs(os.path.join(os.pardir, 'files', 'csv'))
            filename = f'files/csv/statistical_{datetime.now().strftime("%Y%m%d%H%M%S")}.csv'
            res.to_csv(path_or_buf=os.path.join(os.pardir, filename))

            file_path_url.insert_one({'csv': filename})
            return {
                    "code": 200,
                    "格式": "csv",
                    '文件下载地址': 'http://10.16.252.237:5001/' + filename + '/download',
                    'k线图地址': kline_url,
                    '资金曲线图地址': curve_url
                    }

    except Exception as err:
        print(str(err))
        return_json = {'result': 'error'}
        print(return_json)

        return return_json


@app.route('/api/klines/', methods=['POST'])
def klines():
    try:
        # request_data = json.loads(request.data)
        #
        # # 周期
        # rule_type = request_data['ruleType']
        #
        # # 时间范围
        # date_from = request_data['startTime']
        # date_to = request_data['endTime']
        #
        # # 币种
        # symbol = request_data['symbol']
        #
        # # 返回数据类型
        # dtypes = request_data['dtypes'] if request_data['dtypes'] else 'json'

        # 现货

        df = run_backtest_klines()
        dtypes = 'csv'
        if dtypes == 'json':
            if not os.path.exists(os.path.join(os.pardir, 'files', 'json')):
                os.makedirs(os.path.join(os.pardir, 'files', 'json'))
            filename = f'files/json/klines_{datetime.now().strftime("%Y%m%d%H%M%S")}.json'
            df.to_json(path_or_buf=os.path.join(os.pardir, filename), orient='index', force_ascii=False, date_format='iso')

            file_path_url.insert_one({'jsonfiles': filename})

            return {"code": 200, "格式": "jsonfile", '下载地址': 'http://10.16.252.237:5001/'+filename+'/download'}

        elif dtypes == 'csv':
            if not os.path.exists(os.path.join(os.pardir, 'files', 'csv')):
                os.makedirs(os.path.join(os.pardir, 'files', 'csv'))
            filename = f'files/csv/klines_{datetime.now().strftime("%Y%m%d%H%M%S")}.csv'
            df.to_csv(path_or_buf=os.path.join(os.pardir, filename))

            file_path_url.insert_one({'csv': filename})
            return {"code": 200, "格式": "csv", '下载地址': 'http://10.16.252.237:5001/' + filename+'/download'}

    except Exception as err:
        print(str(err))
        return_json = {'result': 'error'}
        print(return_json)

        return return_json


@app.route('/api/trade/', methods=['POST'])
def trade():
    try:
        # request_data = json.loads(request.data)
        #
        # # 策略名称
        # signal_name = request_data['signalName']
        #
        # # 策略参数
        # para = request_data['para']
        # para = eval(para)
        #
        # # 周期
        # rule_type = request_data['ruleType']
        #
        # # 时间范围
        # date_from = request_data['startTime']
        # date_to = request_data['endTime']
        #
        # # 币种
        # symbol = request_data['symbol']
        #
        # # 杠杆
        # leverage_rate = int(request_data['leverageRate'])
        #
        # # 滑点
        # slippage = float(request_data['slippage'])
        #
        # # 手续费
        # c_rate = float(request_data['c_rate'])

        # # 返回数据类型
        # dtypes = request_data['dtypes'] if request_data['dtypes'] else 'json'

        # 回测
        # res, res_df, trade = run_backtest_trade(signal_name=signal_name, para=para, rule_type=rule_type, date_from=date_from,
        #                    date_to=date_to, symbol=symbol, leverage_rate=leverage_rate, slippage=slippage,
        #                    c_rate=c_rate)
        df = run_backtest_trade()
        dtypes = 'csv'
        if dtypes == 'json':
            if not os.path.exists(os.path.join(os.pardir, 'files', 'json')):
                os.makedirs(os.path.join(os.pardir, 'files', 'json'))
            filename = f'files/json/trade_{datetime.now().strftime("%Y%m%d%H%M%S")}.json'
            df.to_json(path_or_buf=os.path.join(os.pardir, filename), orient='index', force_ascii=False, date_format='iso')

            file_path_url.insert_one({'jsonfiles': filename})

            return {"code": 200, "格式": "jsonfile", '下载地址': 'http://10.16.252.237:5001/' + filename + '/download'}

        elif dtypes == 'csv':
            if not os.path.exists(os.path.join(os.pardir, 'files', 'csv')):
                os.makedirs(os.path.join(os.pardir, 'files', 'csv'))
            filename = f'files/csv/trade_{datetime.now().strftime("%Y%m%d%H%M%S")}.csv'
            df.to_csv(path_or_buf=os.path.join(os.pardir, filename))

            file_path_url.insert_one({'csv': filename})

            return {"code": 200, "格式": "csv", '下载地址': 'http://10.16.252.237:5001/' + filename + '/download'}

    except Exception as err:
        print(str(err))
        return_json = {'result': 'error'}
        print(return_json)

        return return_json


@app.route('/<path:filepath>/download/', methods=['GET'])
def download_file(filepath):
    filepath = os.path.join(os.pardir, filepath)
    if os.path.exists(filepath):
        # 下载文件的三种写法
        # app.send_static_file(filepath)   #文件必须再static文件夹里面
        try:
            response = make_response(send_file(filepath))

            return response
        except Exception as err:
            return {"code": 10004, 'msg': '下载文件出错,'+str(err)}
    else:
        return {"code": 10005, 'msg': '没有该文件'}


@app.route('/get_all_files')
def get_all_files():
    # 返回所有文件路径
    all_files_csv = file_path_url.distinct('csv')
    all_files_json = file_path_url.distinct('jsonfiles')
    all_files = all_files_csv+all_files_json
    print(all_files)
    return render_template('test3.html', all_files=all_files)


@app.route('/get_klines', methods=['GET'])
def get_klines():
    uuid = request.args.get('uuid')

    return render_template('test.html', uuid=uuid)


@app.route('/get_curve', methods=['GET'])
def get_curve():
    uuid = request.args.get('uuid')

    return render_template('test2.html', uuid=uuid)


@app.route('/api/deal_data')
def deal_data():
    uuid = request.args.get('uuid')
    if uuid:
        result = collection.find_one({'uuid': uuid})
        data_list = result['klines_data']
        for data in data_list:
            data[0] = data[0].strftime('%Y-%m-%d %H:%M:%S')
            if data[11] != 0:
                data[11] = data[11].strftime('%Y-%m-%d %H:%M:%S')
    else:
        return {'缺少uuid'}

    return {'data_list': data_list}


@app.route('/api/deal_data_curve')
def deal_data_curve():
    uuid = request.args.get('uuid')
    if uuid:
        result = collection.find_one({'uuid': uuid})
        data_list = result['curve_data']

        if type(data_list[0][0]) == 'int':
            for data in data_list:
                data[0] = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(float(data[0]/1000)))
    else:
        return '缺少uuid'
    # print(data_list)
    return {'data_list': data_list}


if __name__ == '__main__':
    app.run(debug=True, host='0.0.0.0', port=5001)